var trackNames = TransformScenarioData()["TrackNames"]; //所有分段飞行数组["黄河几字弯,"一湖两海"]
var trackPartIndex = 0, //分段飞行数组索引
    clickOnePartStatus = false //是否只飞行一段

function initFlyPartContent() {
    var html = ""
    trackNames.map(function(item, index) {
        if (index == "0") {
            html += `<a href="javascript:void(0);" index = ` + index + ` style="color:#FFF;margin-right:10px">` + item + `</a>`
        } else {
            html += `<br/><a href="javascript:void(0);" index = ` + index + ` style="color:#FFF;margin-right:10px">` + item + `</a>`
        }
    })
    $("#part_fly").html(html)
    $("a").click(function(e) {
        clickOnePartStatus = true
        var trackIndex = Number($(e.currentTarget).attr("index"))
        startScenario(trackIndex)
    })
}
/**
 * 开始飞行
 */
function startScenario(trackIndex) {
    removeHotSpotBoards();
    divContainer["partTitle"] = document.createElement("div");
    divContainer["partTitle"].innerHTML = `
            <div class="partFlyTitle">
                ` + trackNames[trackIndex || 0] + `
            </div>`;
    divContainer["partTitle"].style.opacity = "0.9"
    divContainer["partTitle"].style.position = "absolute"
    divContainer["partTitle"].style.top = "80px"
    divContainer["partTitle"].style.left = "80px"
    divContainer["partTitle"].style.backgroundImage = "url(/images/bg_title.png)"
    divContainer["partTitle"].style.backgroundSize = "100% 100%"
    divContainer["partTitle"].style.padding = "20px 30px"
    document.body.appendChild(divContainer["partTitle"])

    setTimeout(function() {
        divContainer["partTitle"].remove()
    }, 5000);

    resetScenarioParams();
    globalParamter = TransformScenarioData(trackNames[trackIndex || 0])["CameraTrack"];
    if (typeof(globalParamter) != "undefined" && globalParamter.length > 0) {
        globalCameraHandle();
    } else {
        console.log("镜头飞行参数不正确！！");
    }
}

/**
 * 开始场景飞行
 */
function flyScenario() {
    marksIndex = 1;
    //系统初始化定位到第一个点位
    var pt = Cesium.Cartographic.fromDegrees(marks[0].X, marks[0].Y, marks[0].Z);
    var ellipsoid = viewer.scene.globe.ellipsoid;

    var cartesian3 = ellipsoid.cartographicToCartesian(pt);
    globleSetCamera({
        "X": cartesian3.x,
        "Y": cartesian3.y,
        "Z": cartesian3.z,
        //"Heading": Cesium.Math.toRadians(bearing(marks[0].Y, marks[0].X, marks[1].Y, marks[1].X))
    }, flyExtent);
    // viewer.scene.camera.flyTo({
    //     destination: Cesium.Cartesian3.fromDegrees(marks[0].X, marks[0].Y, marks[0].Z),
    //     duration: 3 //定位的时间间隔
    // });
    // //延时执行相机飞行操作
    // globalTimeout = setTimeout(function() {
    //     flyExtent();
    // }, 3000);
};

/**
 * 退出场景飞行
 */
function stopScenario() {
    flyCameraBool = false;
    resetScenarioParams();
    removeHotSpotBoards();
    Exection && viewer.clock.onTick.removeEventListener(Exection);
    globalTimeout && window.clearTimeout(globalTimeout);
    globalClearTimeout();
};

/**
 * 重置飞行参数
 */
function resetScenarioParams() {
    globalPartIndex = -1;
    lastExection = Exection;
}

/**
 * 暂停飞行
 */
function pauseScenario() {
    var param = getCameraPosition();
    pauseParamter["camera"] = {
        X: param["position"]["x"],
        Y: param["position"]["y"],
        Z: param["position"]["z"],
        Heading: param["heading"],
        Pitch: param["pitch"],
        Roll: param["roll"]
    };
    pauseParamter["time"] = {
        "start": viewer.clock.startTime,
        "current": viewer.clock.currentTime,
        "stop": viewer.clock.stopTime
    }
    lastExection = Exection;
    Exection && viewer.clock.onTick.removeEventListener(Exection);
    globalTimeout && window.clearTimeout(globalTimeout);
}

/**
 * 继续飞行
 */
function proceedScenario() {
    if (pauseParamter["camera"]) {
        globleSetCamera(pauseParamter["camera"], proceedFlyScenario);
    } else {
        console.log("未获取到暂停相机参数！！");
    }
}

/**
 * 还原飞行任务
 */
function proceedFlyScenario() {
    if (lastExection && pauseParamter["time"]) {
        var startTime = pauseParamter["time"]["start"];
        var stopTime = pauseParamter["time"]["stop"];
        viewer.clock.startTime = startTime.clone(); // 开始时间
        viewer.clock.stopTime = stopTime.clone(); // 结束时间
        viewer.clock.currentTime = pauseParamter["time"]["current"]; // 当前时间
        viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式：到时间后时钟将停止
        viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。
        viewer.clock.onTick.addEventListener(lastExection);
    }
}
/*
 * 飞行执行函数
 */
function flyExtent() {
    var pitch = Cesium.Math.toRadians(pitchValue);
    // 设置时钟
    setExtentTime(marks[marksIndex].FlyTime);
    Exection = function TimeExecution() {
        var preIndex = marksIndex - 1;
        if (marksIndex == 0) {
            preIndex = marks.length - 1;
        }
        var degreesHeading = bearing(marks[preIndex].Y, marks[preIndex].X, marks[marksIndex].Y, marks[marksIndex].X);
        console.log(degreesHeading);
        // var heading = bearing(marks[preIndex].Y, marks[preIndex].X, marks[marksIndex].Y, marks[marksIndex].X);
        heading = Cesium.Math.toRadians(degreesHeading);
        // 当前已经过去的时间，单位s
        var delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
        var originLat = marksIndex == 0 ? marks[marks.length - 1].Y : marks[marksIndex - 1].Y;
        var originLng = marksIndex == 0 ? marks[marks.length - 1].X : marks[marksIndex - 1].X;
        var flytime = marks[marksIndex].FlyTime / 1000;
        var endPosition = Cesium.Cartesian3.fromDegrees(
            (originLng + (marks[marksIndex].X - originLng) / flytime * delTime),
            (originLat + (marks[marksIndex].Y - originLat) / flytime * delTime),
            marks[marksIndex].Z
        );
        //如果存在下一转线段，计算下一转角的角度
        var headingNext = 0;
        if (marks[marksIndex + 1]) {
            headingNext = bearing(marks[marksIndex].Y, marks[marksIndex].X, marks[marksIndex + 1].Y, marks[marksIndex + 1].X);
            console.log(degreesHeading);
            if (headingNext > degreesHeading) {
                var DifferenceValue = headingNext - degreesHeading;
                if (DifferenceValue > 180) {
                    DifferenceValue = DifferenceValue - 360;
                }
                heading = Cesium.Math.toRadians(degreesHeading + DifferenceValue / flytime * delTime);
            } else {
                var DifferenceValue = degreesHeading - headingNext;
                if (DifferenceValue > 180) {
                    DifferenceValue = DifferenceValue - 360;
                }
                heading = Cesium.Math.toRadians(degreesHeading - DifferenceValue / flytime * delTime);
            }
        }
        // viewer.camera.lookAt(endPosition, new Cesium.HeadingPitchRange(heading, pitch, marks[marksIndex].Z));
        viewer.scene.camera.setView({
            destination: endPosition,
            orientation: {
                heading: heading,
                pitch: pitch,
            }
        });
        //若预设该飞行时间已过期，则清空监听事件并原地转向
        if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
            viewer.clock.onTick.removeEventListener(Exection);
            //changeCameraHeading();
            marksIndex++;
            if (marksIndex >= marks.length) {
                globalCameraHandle();
            } else {
                flyExtent();
            }
        }
    };
    viewer.clock.onTick.addEventListener(Exection);
}

/**
 * 相机原地定点转向
 */
function changeCameraHeading() {
    var nextIndex = marksIndex + 1;
    if (marksIndex == marks.length - 1) {
        // nextIndex = 0;
        globalCameraHandle();
        return;
    }
    // 计算两点之间的方向
    var heading = bearing(marks[marksIndex].Y, marks[marksIndex].X, marks[nextIndex].Y, marks[nextIndex].X);
    // console.log("判断后角度" + heading);
    //heading = heading > 180 ? 360 - heading : heading;
    // console.log("判断前角度" + heading);
    // 相机看点的角度，如果大于0那么则是从地底往上看，所以要为负值
    var pitch = Cesium.Math.toRadians(pitchValue);
    // 给定飞行一周所需时间，比如10s, 那么每秒转动度数
    var angle = (heading - Cesium.Math.toDegrees(viewer.camera.heading)) / 2;
    // 时间间隔2秒钟
    setExtentTime(2000);
    // 相机的当前方向
    var initialHeading = viewer.camera.heading;
    console.log("当前视角为" + Cesium.Math.toDegrees(initialHeading));
    console.log("视角需调整" + angle);
    if (angle < -90) {
        angle = 180 + angle
    } else if (angle > 90) {
        angle = angle - 180;
    }
    var initialPitch = viewer.camera.pitch;
    var initialRoll = viewer.camera.roll;
    Exection = function() {
        // 当前已经过去的时间，单位s
        var delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
        var heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
        viewer.scene.camera.setView({
            orientation: {
                heading: heading,
                pitch: pitch,
                // roll: initialRoll
            }
        });
        //相机原地转完执行飞往下一点事件
        if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
            viewer.clock.onTick.removeEventListener(Exection);
            marksIndex++;
            if (marksIndex >= marks.length) {
                globalCameraHandle();
            } else {
                flyExtent();
            }
        }
    };
    viewer.clock.onTick.addEventListener(Exection);
}

/**
 * 设置飞行的时间到viewer的时钟里
 * @param {*} time  时间  单位秒
 */
function setExtentTime(time) {
    var startTime = Cesium.JulianDate.fromDate(new Date());
    var stopTime = Cesium.JulianDate.addSeconds(startTime, time / 1000, new Cesium.JulianDate());
    viewer.clock.startTime = startTime.clone(); // 开始时间
    viewer.clock.stopTime = stopTime.clone(); // 结束时间
    viewer.clock.currentTime = startTime.clone(); // 当前时间
    viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式：到时间后时钟将停止
    viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。
    viewer.clock.multiplier = viewerClockMultiplier;
}

/**
 * 绕点飞行一周
 * @param {*} position 定位
 * @param {*} time 时间 单位 毫秒
 * @param {*} pitch 俯仰角  度
 * @param {*} distance 距离点位的距离
 * @param {*} circle 要转几圈
 */
function OrbitFlight(position, time, pitch, distance, circle) {
    time = time ? (time / 1000) : 30;
    var options = {
        lng: 109.70065490293072,
        lat: 39.58077810030326,
        height: 15.8,
        heading: 0.0,
        pitch: 0.0,
        roll: 0.0
    };
    var position = Cesium.Cartesian3.fromDegrees(options.lng, options.lat, options.height);
    // 相机看点的角度，如果大于0那么则是从地底往上看，所以要为负值，这里取-45度
    pitch = Cesium.Math.toRadians(pitch ? pitch : -45);
    // 给定飞行一周所需时间
    var angle = 360 / time / (circle ? circle : 1);
    // 给定相机距离点多少距离飞行，这里取值为5000m
    var distance = distance || 5000;
    var startTime = Cesium.JulianDate.fromDate(new Date());
    var stopTime = Cesium.JulianDate.addSeconds(startTime, time, new Cesium.JulianDate());
    viewer.clock.startTime = startTime.clone(); // 开始时间
    viewer.clock.stopTime = stopTime.clone(); // 结速时间
    viewer.clock.currentTime = startTime.clone(); // 当前时间
    viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式
    viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。
    // 相机的当前heading
    var initialHeading = viewer.camera.heading;
    var Exection = function TimeExecution() {
        // 当前已经过去的时间，单位s
        var delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
        var heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
        viewer.scene.camera.setView({
            destination: position, // 点的坐标
            orientation: {
                heading: heading,
                pitch: pitch
            }
        });
        viewer.scene.camera.moveBackward(distance);
        if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
            viewer.clock.onTick.removeEventListener(Exection);
        }
    };
    viewer.clock.onTick.addEventListener(Exection);
}

/**
 * 公用飞行时间处理函数
 * @returns 
 */
function globalCameraHandle() {
    entitiesHandle("2");
    globalPartIndex++;
    if (globalPartIndex >= globalParamter.length) {
        trackPartIndex++
        //是否只飞一个
        if (clickOnePartStatus) {
            trackPartIndex = 0;
            clickOnePartStatus = false;
            removeHotSpotBoards();
            return console.log("飞行结束啦！！");
        } else {
            if (trackPartIndex < trackNames.length) {
                startScenario(trackPartIndex);
                return console.log("下一个Part");
            } else {
                trackPartIndex = 0;
                removeHotSpotBoards();
                return console.log("飞行结束啦！！");
            }
        }
    }
    var params = globalParamter[globalPartIndex];
    var activativeMap = activatiesHandle(params.Activaties);
    globalParamter[globalPartIndex]["entities"] = activativeMap;
    entitiesHandle("1", activativeMap);
    switch (params.Action) {
        case "SetCamera":
            globalTimeout = setTimeout(function() {
                globleSetCamera(params, globalCameraHandle);
            }, params.Time);
            gototime = params.Duration;
            break;
        case "Goto":
            marks = params.Path;
            var pList = [];
            for (var l = 0; l < marks.length; l++) {
                // pList.push([marks[l].X, marks[l].Y]);
                pList.push(marks[l].X);
                pList.push(marks[l].Y);
            }
            // var line = viewer.entities.add({
            //     name: 'Red line on terrain',
            //     polyline: {
            //         positions: Cesium.Cartesian3.fromDegreesArray(pList),
            //         width: 5,
            //         material: Cesium.Color.RED,
            //         clampToGround: true
            //     }
            // })
            globalTimeout = setTimeout(function() {
                flyScenario();;
            }, params.Time);
            break;
        default:
            break;
    }
}

var hotSpotBoard = [];
var divContainer = {};
/**
 * 添加HotSpotBoard
 */
function addHotSpotBoards() {
    let position = Cesium.Cartesian3.fromDegrees(109.70065490293072, 39.58077810030326, 944.63);
    hotSpotBoard = new CustomBoard(viewer, position, {
        chineseTitle: "攀登点1",
        englishTitle: "Climbing point 1",
        bgImageUrl: "/images/hotspotboard",
        level: 5000000
    });
}
/**
 * 删除HotSpotBoard和所有实体
 */
function removeHotSpotBoards() {
    for (var i in hotSpotBoard) {
        hotSpotBoard[i].customBoard.windowClose();
    }
    for (var i in divContainer) {
        divContainer[i].remove();
    }
    viewer.entities.removeAll();
}

/**
 * 删除文本框
 * @param {*} key  "黄河入蒙第一站说明"
 */
function removeDivContainer(key) {
    divContainer[key] && divContainer[key].remove()
}

/**
 * 渲染实体数据\自定义富文本\数据服务
 * @param {*} entity 
 */
function renderEntity(entity) {
    // var ScenarioData = TransformScenarioData()["CameraTrack"] //飞行数据测试
    // var actor = ScenarioData[0].Activaties[0].Actor//点测试EntityActor
    // entity = ScenarioData[0].Activaties[0].Entities[0]//点测试
    // entity = ScenarioData[2].Activaties[1].Entities[0]//线测试
    // entity = ScenarioData[1].Activaties[0].Entities//富文本测试
    // var actor = ScenarioData[1].Activaties[0].Actor//富文本测试
    var actor = entity.Actor
    switch (actor) {
        case "EntityActor":
            var geometry = entity.Geometry.geometry
            var symbol = entity.Symbol
            switch (geometry.type) {
                case "Point":
                    var position = Cesium.Cartesian3.fromDegrees(geometry.coordinates[0], geometry.coordinates[1], 0);
                    var obj = new CustomBoard(viewer, position, {
                        chineseTitle: symbol.entityName,
                        englishTitle: "",
                        bgImageUrl: "/images/hotspotboard",
                        level: 5000000
                    });
                    hotSpotBoard.push({
                        "customBoard": obj,
                        "title": symbol.entityName
                    })
                    break;
                case "LineString":
                    var polylinePoints = []
                    geometry.coordinates.map(function(onePoint) {
                        polylinePoints.push(onePoint[0])
                        polylinePoints.push(onePoint[1])
                    })
                    var entity = viewer.entities.add({
                        name: 'pathLine',
                        polyline: {
                            clampToGround: true,
                            material: new xt3d.PolylineObject.PolylineSpriteMaterialProperty({
                                duration: 2000, //控制速度
                                url: "/images/hotspotboard/spriteline1.png" //材质路径
                            }),
                            positions: Cesium.Cartesian3.fromDegreesArray(polylinePoints),
                            width: 15
                        }
                    });
                    break;
                case "Polygon":

                    break;
                default:
                    break;
            }
            break;
        case "CustomActor":
            divContainer[entity.containerIndex] = document.createElement("div");
            var txtContent = entity.Details
            switch (entity.Type) {
                case "HTML":
                    divContainer[entity.containerIndex].innerHTML =
                        `<div class="">
                            <div class="txtBoxTitle">
                                ` + txtContent.Title + `
                            </div>
                            <div class="txtBoxContent">
                                ` + txtContent.Content + `
                            </div>
                        </div>`;

                    divContainer[entity.containerIndex].style.backgroundImage = "url(/images/bg_border.png)"
                    divContainer[entity.containerIndex].style.backgroundSize = "100% 100%"
                    divContainer[entity.containerIndex].style.padding = "40px"
                    break;
                case "image":
                    divContainer[entity.containerIndex].innerHTML =
                        `
                        <img src="` + txtContent.src + `" style="width:100%;height:100%">
                        `;
                    break;
                case "video":
                    divContainer[entity.containerIndex].innerHTML =
                        `<video controls>
                            <source src="` + txtContent.src + `" type="video/mp4">
                        </video>`;
                    break;
                default:
                    break;
            }
            var div_opacity = !entity.Transparent ? "100" : entity.Transparent
            divContainer[entity.containerIndex].style.opacity = (Number(div_opacity) / 100).toFixed(1)
            var containerStr = entity.Container
            var container = containerStr.split(",")
            divContainer[entity.containerIndex].style.width = container[2] + "px"
            divContainer[entity.containerIndex].style.position = "absolute"
            switch (entity.Position) {
                case "BottomLeft":
                    divContainer[entity.containerIndex].style.bottom = container[0] + "px"
                    divContainer[entity.containerIndex].style.left = container[1] + "px"
                    break;
                case "BottomRight":
                    divContainer[entity.containerIndex].style.bottom = container[0] + "px"
                    divContainer[entity.containerIndex].style.right = container[1] + "px"
                    break;
                case "TopLeft":
                    divContainer[entity.containerIndex].style.top = container[0] + "px"
                    divContainer[entity.containerIndex].style.left = container[1] + "px"
                    break;
                case "TopRight":
                    divContainer[entity.containerIndex].style.top = container[0] + "px"
                    divContainer[entity.containerIndex].style.right = container[1] + "px"
                    break;
                default:
                    break
            }
            document.body.appendChild(divContainer[entity.containerIndex])
            break;
        case "LayerActor":
            break;
        default:
            break;
    }
}